#=
    LocalTime values are held this way:
       local_time is universal_time + UTM2LCL[1]
=#
struct LocalTime <: AbstractClock
     value::Int4Time
end

@inline value(x::LocalTime) = x.value
@inline Base.eltype(::Type{LocalTime}) = Int4Time
@inline LocalTime(x::LocalTime) = x

@inline Clock(x::LocalTime) = Clock(value(x))
@inline LocalTime(x::Clock) = LocalTime(value(x))

isuniversaltime(x::LocalTime) = false
isuniversaltime(x::T) where T = null

islocaltime(x::LocalTime) = true
islocaltime(x::UniversalTime) = false
islocaltime(x::T) where T = null

LocalTime() = LocalTime(UniversalTime())

Base.Dates.DateTime(x::LocalTime) = Base.Dates.DateTime(Clock(x))
Base.Dates.Date(x::LocalTime) = Base.Dates.Date(Clock(x))
Base.Dates.Time(x::LocalTime) = Base.Dates.Time(Clock(x))

LocalTime(x::Base.Dates.DateTime) = LocalTime(Clock(x))
LocalTime(x::Base.Dates.Date) = LocalTime(Clock(x))

# This is the recommended conversion direction.
@inline LocalTime(x::UniversalTime) =
    LocalTime(value(x) + nanoseconds(UTM2LCL[1]))

#=
   This version first refreshes UTM2LCL:
     if there has been a transition from
     local standard time to daylight time,
     or from daylight time to standard time,
     the conversion constant will be updated
   before it is applied.
=#

function LocalTime(x::UniversalTime, refresh::Bool)
    refresh && refresh_universal_to_local()
    return LocalTime(x)
end

# This is an UNSAFE conversion direction.
#
#    Whenever possible, convert from UniversalTime to LocalTime.
#    The result of this call is likely to be inconsistent
#    with tier 1 clocks annually, for at least a half-hour.
#
@inline UniversalTime(x::LocalTime) =
     UniversalTime(value(x) - nanoseconds(UTM2LCL[1]))

Base.string(x::LocalTime) = string(Clock(x), UTMoffset_formatted())
Base.show(io::IO, x::LocalTime) = print(io, string(x))

function Base.parse(::Type{LocalTime}, x::String)
    sign = substr_offset_from_end(x,5,5)[1]
    if sign != POSITIVE && sign != NEGATIVE && sign != '-'
        clock = parse(Clock, x)
    else
        clock = parse(Clock, substr(x, 1, length(x)-6))
    end
    return LocalTime(clock)
end

LocalTime(x::S) where S<:AbstractString = parse(LocalTime, x)

function LocalTime(yr::I, mo::I=one(I), dy::I=one(I), hr::I=zero(I), mn::I=zero(I), sc::I=zero(I),
                  milli::I=zero(I), micro::I=zero(I), nano::I=zero(I)) where I<:Integer
    return LocalTime(Clock(yr, mo, dy, hr, mn, sc, milli, micro, nano))
end

